//
//  UUOrderManager.m
//  UUCharterSupplier
//
//  Created by ZhangAo on 22/01/2018.
//  Copyright © 2018 UUCharter. All rights reserved.
//

#import "UUOrderManager.h"
#import <UUFoundation/UUIncrementDataManager.h>
#import "UUOrderUtility.h"
#import <UUFoundation/DKDataManager.h>
#import "UUOrderRequestModel.h"
#import "UUOrderConfirmRequestModel.h"
#import "UUOrderAssignRequestModel.h"
#import "UUOrderDetailRequestModel.h"

@interface UUOrderManager ()

@property (nonatomic, strong) UUIncrementDataManager *orderDataManager;

@end

@implementation UUOrderManager

- (instancetype)init {
    self = [super init];
    if (self) {
        self.orderDataManager = [UUIncrementDataManager managerWithConfiguration:
                                 [UUIncrementDataManagerConfiguration configurationWithRequestModelClass:[UUOrderRequestModel class]
                                                                                                isTwoWay:YES
                                                                                          storeContainer:[UUOrderUtility orderPrivateDefaults]]];
    }
    
    return self;
}

- (void)asyncUpdateOrders {
    WEAK_SELF();
    [self.orderDataManager asyncIncrementUpdateWithCompleteBlock:^(BOOL hadUpdate, NSArray<id> *insert, NSArray<id> *delete, NSError *error) {
        if (hadUpdate) {
            if (insert.count > 0) {
                [weakSelf notifyObserversWithSelector:@selector(orderManagerDidUpdateOrders:) withObject:insert];
            } else {
                [weakSelf notifyObserversWithSelector:@selector(orderManagerDidRemoveOrders:) withObject:delete];
            }
        }
    }];
}

- (NSArray<id> *)fetchOrdersForStatus:(UUOrderStatus)status {
    return [self fetchOrdersForStatus:status beforeUpdateTime:0];
}

- (UUOrderModel *)fetchOrderWithOrderId:(id)orderId {
    return (UUOrderModel *)[self.orderDataManager fetchModelWithPrimaryKeyValue:orderId];
}

- (void)asyncFetchOrderHistoryListForOrderId:(id)orderId length:(int)length completeBlock:(void (^)(NSArray<id> *orders, NSError *error))completeBlock {
    DKAssert(orderId != nil);
    
    [self.orderDataManager asyncFetchHistoryWithLength:length completeBlock:^(BOOL hadUpdate, NSError *error) {
        if (error == nil) {
            if (hadUpdate) {
                UUOrderModel *order = [self fetchOrderWithOrderId:orderId];
                completeBlock([self fetchOrdersForStatus:UUOrderStatusNone beforeUpdateTime:order.updateTime], nil);
            } else {
                completeBlock(nil, nil);
            }
        } else {
            completeBlock(nil, error);
        }
    }];
}

- (void)asyncConfirmOrderWithOrderId:(id)orderId confirm:(BOOL)confirm completeBlock:(void (^)(NSError *error))completeBlock {
    UUOrderConfirmRequestModel *requestModel = [UUOrderConfirmRequestModel new];
    requestModel.type = confirm ? @"confirm" : @"refuse";
    requestModel.orderId = orderId;
    
    WEAK_SELF();
    [[DKDataManager new] requestWithRequestModel:requestModel completedBlock:^(DKResponseModel *responseModel, NSError *error) {
        if (error == nil) {
            [weakSelf asyncUpdateOrders];
        }
        
        BLOCK_SAFE_CALLS(completeBlock, error);
    }];
}

- (void)asyncAssignOrderWithOrderId:(id)orderId
                         dispatches:(NSArray<UUOrderDispatchItemModel *> *)dispatches
                      completeBlock:(void (^)(NSError *error))completeBlock {
    UUOrderAssignRequestModel *requestModel = [UUOrderAssignRequestModel new];
    requestModel.orderId = orderId;
    requestModel.type = @"dispatch";
    requestModel.dispatch = dispatches;
    
    WEAK_SELF();
    [[DKDataManager new] requestWithRequestModel:requestModel completedBlock:^(DKResponseModel *responseModel, NSError *error) {
        if (error == nil) {
            [weakSelf asyncUpdateOrders];
        }
        
        BLOCK_SAFE_CALLS(completeBlock, error);
    }];
}

- (void)asyncFetchOrderDetailWithOrderId:(id)orderId
                           completeBlock:(void (^)(UUOrderDetailModel *, NSError *))completeBlock {
    UUOrderDetailRequestModel *requestModel = [UUOrderDetailRequestModel new];
    requestModel.orderId = orderId;
    
    [[DKDataManager new] requestWithRequestModel:requestModel completedBlock:^(DKResponseModel *responseModel, NSError *error) {
        if (error == nil) {
            UUOrderDetailModel *order = (UUOrderDetailModel *)responseModel;
            BLOCK_SAFE_CALLS_In_Main_Queue(completeBlock, order ,nil);
        } else {
            BLOCK_SAFE_CALLS_In_Main_Queue(completeBlock, nil ,error);
        }
    }];
}

#pragma mark - Private methods

- (NSArray<id> *)fetchOrdersForStatus:(UUOrderStatus)status beforeUpdateTime:(NSTimeInterval)updateTime {
    NSMutableString *where = [NSMutableString new];
    if (status != UUOrderStatusNone) {
        [where appendFormat:@"status = %ld", status];
    }
    
    if (updateTime != 0) {
        if (where.length > 0) {
            [where appendString:@" and "];
        }
        
        [where appendFormat:@"updateTime < %f", updateTime];
    }
    
    return [UUOrderModel searchColumn:@"id" where:where orderBy:@"departTime desc" offset:0 count:0];
}

@end
